#pragma once

#include<QString>
#include<QIcon>
#include<QUuid>
#include<QDebug>
#include<QFile>
#include<QFileInfo>
#include<QDateTime>
#include<QPixmap>
#include <QList>
#include"base.qpb.h"
#include"file.qpb.h"
#include"friend.qpb.h"
#include"gateway.qpb.h"
#include"message.qpb.h"
#include"notify.qpb.h"
#include"speech.qpb.h"
#include"transmit.qpb.h"
#include"user.qpb.h"

namespace model
{



///////////////////////////////////////////////////////////////
/// 工具函数，后续可能很多模块都需要用到
///////////////////////////////////////////////////////////////


//LOG模块
static inline QString getFileName(const QString& path)
{
    return QFileInfo(path).fileName();
}

//使用方法LOG()<<所需日志记录内容;
#define TAG QString("[%1:%2]").arg(model::getFileName(__FILE__),QString::number(__LINE__))
#define LOG() qDebug().noquote()<<TAG


//Time模块
//将秒级时间戳格式化为QString
static inline QString toFormatTime(int64_t timestamp)
{
    QDateTime dataTime = QDateTime::fromSecsSinceEpoch(timestamp);
    return dataTime.toString("MM-dd HH:mm:ss");
}
//格式化获取当前时间
static inline int64_t getCurrentTime()
{
    return QDateTime::currentSecsSinceEpoch();
}

//从指定文件中，读取所有的二进制文件，返回QByteArray类型数据
static inline QByteArray loadFileToByteArray(const QString& path)
{
    QFile file(path);
    if(!file.open(QFile::ReadOnly))
    {
        LOG()<<"文件打开失败，path = "<<path;
        return QByteArray();
    }
    QByteArray cont = file.readAll();
    if(cont.isEmpty())
        LOG()<<"读取到的文件是空的，path = "<<path;
    file.close();
    return cont;
}
//将二进制数据写入到文件中
static inline void writeByteArrayToFile(const QString& path,const QByteArray& content)
{
    QFile file(path);
    if(!file.open(QFile::WriteOnly))
    {
        LOG()<<"写入文件打开失败,path = "<<path;
        return;
    }
    file.write(content);
    file.flush();
    file.close();
}

//Make模块
static inline QIcon makeIcon(const QByteArray& byteArray)
{
    QPixmap pixmap;
    pixmap.loadFromData(byteArray);
    return QIcon(pixmap);
}






///////////////////////////////////////////////////////////////
/// 用户信息
///////////////////////////////////////////////////////////////

class UserInfo
{
public:
    QString userId;
    QString nickname;
    QString phone;
    QString description;
    QIcon avatar;

    void load(const zzy_mims::UserInfo& userInfo)
    {
        userId = userInfo.userId();
        nickname = userInfo.nickname();
        phone=userInfo.phone();
        description=userInfo.description();
        if(userInfo.avatar().isEmpty())
            avatar=QIcon(":/myResource/Image/dogAvatar.svg");
        else
        avatar=makeIcon(userInfo.avatar());
    }
};


///////////////////////////////////////////////////////////////
/// 消息信息
///////////////////////////////////////////////////////////////


enum class MessageType
{
    TEXT_TYPE,
    IMAGE_TYPE,
    FILE_TYPE,
    SPEECH_TYPE
};

class Message
{
public:
    QString messageId;
    QString chatSessionId;//单聊是对方的名字，群聊就是群聊本身的名字
    QString time;
    MessageType messageType = MessageType::TEXT_TYPE;
    UserInfo sender;
    QByteArray content;
    QString fileId;//只有非文本消息存在，文本消息是空
    QString fileName;//只有文件消息存在


    void load(zzy_mims::MessageInfo msgInfo)
    {
        messageId = msgInfo.messageId();
        chatSessionId = msgInfo.chatSessionId();
        time = toFormatTime(getCurrentTime());
        sender.load(msgInfo.sender());

        switch(msgInfo.message().messageType())
        {
            case zzy_mims::MessageTypeGadget::MessageType::STRING:
            {
                messageType = MessageType::TEXT_TYPE;
                content = msgInfo.message().stringMessage().content().toUtf8();
                break;
            }
            case zzy_mims::MessageTypeGadget::MessageType::FILE:
            {
                messageType = MessageType::FILE_TYPE;
                if(msgInfo.message().fileMessage().hasFileContents())
                    content = msgInfo.message().fileMessage().fileContents();
                if(msgInfo.message().fileMessage().hasFileId())
                    fileId = msgInfo.message().fileMessage().fileId();
                fileName = msgInfo.message().fileMessage().fileName();
                break;
            }
            case zzy_mims::MessageTypeGadget::MessageType::SPEECH:
            {
                messageType = MessageType::SPEECH_TYPE;
                if(msgInfo.message().speechMessage().hasFileContents())
                    content = msgInfo.message().speechMessage().fileContents();
                if(msgInfo.message().speechMessage().hasFileId())
                    fileId = msgInfo.message().speechMessage().fileId();
                break;
            }
            case zzy_mims::MessageTypeGadget::MessageType::IMAGE:
            {
                messageType = MessageType::IMAGE_TYPE;
                if(msgInfo.message().imageMessage().hasImageContent())
                    content = msgInfo.message().imageMessage().imageContent();
                if(msgInfo.message().imageMessage().hasFileId())
                    fileId = msgInfo.message().imageMessage().fileId();
                break;
            }
            default:
            {
                LOG()<<"错误的消息类型，MessageType:"<<msgInfo.message().messageType();
            }

        }

    };

    static Message makeMessage(const MessageType messageType,const QString& chatSessionId,const UserInfo& sender,
                               const QByteArray& content,const QString& extraInfo)
    {
        switch (messageType)
        {
        case MessageType::TEXT_TYPE:
            return makeTextMessage(chatSessionId,sender,content);
            break;
        case MessageType::IMAGE_TYPE:
            return makeImageMessage(chatSessionId,sender,content);
            break;
        case MessageType::FILE_TYPE:
            return makeFileMessage(chatSessionId,sender,content,extraInfo);
            break;
        case MessageType::SPEECH_TYPE:
            return makeSpeechMessage(chatSessionId,sender,content);
            break;
        default:
            return Message();
            break;
        }


    };
private:
    static QString makeId()
    {
        //M+从UUID算法生成的随机数中取最后纯数字一部分
        return "M"+QUuid::createUuid().toString().sliced(25,11);
    }

    static Message makeTextMessage(const QString& chatSessionId,const UserInfo& sender,const QByteArray& content)
    {
        Message msg;
        msg.messageType = MessageType::TEXT_TYPE;
        msg.chatSessionId = chatSessionId;
        msg.sender = sender;
        msg.content = content;
        //文本消息没有文件属性
        msg.fileId = "";
        msg.fileName="";

        msg.messageId = makeId();
        msg.time = toFormatTime(getCurrentTime());

        return msg;
    }
    static Message makeImageMessage(const QString& chatSessionId,const UserInfo& sender,const QByteArray& content)
    {
        Message msg;
        msg.messageType = MessageType::IMAGE_TYPE;
        msg.chatSessionId = chatSessionId;
        msg.sender = sender;
        msg.content = content;
        // fileId后续的时候再设置
        msg.fileId = "";
        // fileName不使用
        msg.fileName="";

        msg.messageId = makeId();
        msg.time = toFormatTime(getCurrentTime());

        return msg;
    }
    static Message makeFileMessage(const QString& chatSessionId,const UserInfo& sender,const QByteArray& content,const QString& FileName)
    {
        Message msg;
        msg.messageType = MessageType::FILE_TYPE;
        msg.chatSessionId = chatSessionId;
        msg.sender = sender;
        msg.content = content;
        // fileId后续的时候再设置
        msg.fileId = "";
        msg.fileName = FileName;

        msg.messageId = makeId();
        msg.time = toFormatTime(getCurrentTime());

        return msg;
    }
    static Message makeSpeechMessage(const QString& chatSessionId,const UserInfo& sender,const QByteArray& content)
    {
        Message msg;
        msg.messageType = MessageType::SPEECH_TYPE;
        msg.chatSessionId = chatSessionId;
        msg.sender = sender;
        msg.content = content;
        // fileId后续的时候再设置
        msg.fileId = "";
        // fileName不使用
        msg.fileName="";

        msg.messageId = makeId();
        msg.time = toFormatTime(getCurrentTime());

        return msg;
    }


};


///////////////////////////////////////////////////////////////
/// 会话信息
///////////////////////////////////////////////////////////////

class SessionInfo
{
public:
    QString chatSessionId;
    QString chatSessionName;//单聊是对方的名字，群聊就是群聊本身的名字
    Message lastMessage;
    QIcon avatar;
    QString userId;

    void load(const zzy_mims::ChatSessionInfo& sInfo)
    {
        chatSessionId = sInfo.chatSessionId();
        chatSessionName = sInfo.chatSessionName();
        if(sInfo.hasSingleChatFriendId())
            userId = sInfo.singleChatFriendId();
        if(sInfo.hasPrevMessage())
            lastMessage.load(sInfo.prevMessage());
        if(sInfo.hasAvatar()&&!sInfo.avatar().isEmpty())
            avatar = makeIcon(sInfo.avatar());
        else
        {
            //单聊
            if(userId!="")
                avatar = QIcon(":/myResource/Image/dogAvatar.svg");
            else
                avatar = QIcon(":/myResource/Image/groupSession.svg");
        }
    }
};

}//end model
